home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / simcode.arc / MAINSIM.PAS < prev    next >
Pascal/Delphi Source File  |  1985-02-14  |  18KB  |  637 lines

  1. {$symtab-,$pagesize:86,$linesize:96,$debug-,
  2. $title:'MAINSIM.PAS -- Main Routine for Terminal Simulator'}
  3. {    COPYRIGHT @ 1982
  4.     Jim Holtman and Eric Holtman
  5.     35 Dogwood Trail
  6.     Randolph, NJ 07869
  7.     (201) 361-3395
  8. }
  9. {$include:'arglist.inc'}
  10. {$list-}
  11. {$include:'filkqq.inc'}
  12. {$list+, FILKQQ.INC included}
  13.  
  14.  program simterm(output,input);
  15.  
  16.      uses
  17.      arglist,filkqq;       {$include:'simterm.inc'}
  18.  
  19.      const
  20.      Alt_C = 46;           {Alternate C - log file switch}
  21.      Alt_D = 32;           {Alternate D - Dump the file to Comm line}
  22.      Alt_F = 33;           {Alternate F - turn on line edit mode}
  23.       Alt_E = 18;           {toggle the vi_cursor mode}
  24.      Alt_H = 35;           { Help screen }
  25.      Alt_K = 37;           { Alternate login functions }
  26.      Alt_L = 38;           { Executing login scripts }
  27.      Alt_R = 19;           {XModem Receive}
  28.      Alt_T = 20;           {XModem Transmit}
  29.      Alt_P = 25;            {Toggle Prime editting mode}
  30.      Alt_V = 47;           {Ventel functions entry point }
  31.      F1 = 59;           {function key 1}
  32.      F2 = 60;           {function key 2}
  33.      F3 = 61;           {function key 3}
  34.      F5 = 63;           {function key 5, send an "l" (for reading notes) }
  35.      F6 = 64;           {function key 6, send a "j" (for reading notes) }
  36.      F8 = 66;           {function key 8}
  37.      Alt_F1 = 104;           {Alternate F1}
  38.      Alt_F2 = 105;           {Alternate F2}
  39.      Alt_F3 = 106;           {Alternate F3}
  40.      Alt_F4 = 107;           {Alternate F4 -- toggle the masking bit}
  41.      Alt_F5 = 108;           {Alternate F5 -- clear 25th line}
  42.      Alt_F6 = 109;           {Alternate F6 -- display modes on 25th line}
  43.      Alt_F10 = 113;    {Exit, but clear screen first}
  44.      HOME = 71;           {HOME key}
  45.      PrtSc = 114;           {CNTL-PrtSc}
  46.      CNTL_Pg_Dn = 118;       {Download -- UNIX -> IBM}
  47.      CNTL_Pg_Up = 132;       {Upload -- IBM -> UNIX}
  48.      Alt_1 = 120;
  49.      Alt_0 = 129;
  50.      Alt_MINUS = 130;
  51.      Alt_EQUAL = 131;
  52.  
  53.      type
  54.      screen_buffer = array [1..4000] of byte;
  55.  
  56.      var
  57.      adm_sim_flag [public] : boolean;
  58.      answer : lstring(10);
  59.      bbs_filename [external] : lstring(64);
  60.      bbs_numbers [public] : boolean ;
  61.      prime_mode [public] : boolean;
  62.      bios_data_ptr : ads of array[0..99] of byte;
  63.      ca : integer;
  64.      cesxqq [external] : word; {load address for SIMTERM}
  65.      ch : integer;
  66.      char_graphics [public] : boolean;
  67.      cold_start : boolean;
  68.      direct_connect : boolean;
  69.      display_buffer_addr [public] : word;
  70.      display_columns [public] : boolean;
  71.      display_control [public] : boolean;
  72.      emacs_flag [public] : boolean;
  73.      first_script [public] : lstring(20);
  74.      fts_sense : boolean;
  75.      function_keys [public] : array[1..10] of lstring(30);
  76.      graftrax [public] : boolean;
  77.      half_duplex : boolean;
  78.      hayes_modem [public] : boolean;
  79.      hp_sim_flag [public] : boolean;
  80.      i,x,y : integer;
  81.      ignore_char : integer;
  82.      ignore_dels [public] : boolean;
  83.      ignore_rubout [public] : boolean;
  84.      inch : char;
  85.      insert_mode [external] : boolean;
  86.      interrupt_set : boolean;
  87.      irq_num : integer;
  88.      keych : char;
  89.      keycnt : integer;
  90.      key_file : text;
  91.      last_bbs [public] : integer ;
  92.      line_buf : lstring(81);   {line buffer for ENTER}
  93.      line_edit [public] : boolean;
  94.      log_file [public] : file of char;
  95.      log_flag [public] : boolean;
  96.      lpt_only_flag [public] : boolean;
  97.      max_bbs [public] : integer ;
  98.      menufil : lstring(30);
  99.      num_chars : integer;
  100.      outfile : lstring(100);
  101.      param : lstring(40);
  102.      parity : word;
  103.      parity_mask [external] : integer;
  104.      port_num : integer;
  105.      recv_reset [external] : boolean;
  106.      retrace_flag [public] : boolean;
  107.      rogue_mode [public] : boolean;
  108.                    {true if we're playing rogue}
  109.      s2 : string(2);
  110.      script_file [public] : lstring(20);
  111.      script_verbose [public] : boolean;
  112.      scroll_top [public]: integer;
  113.                    { where the 'top' is for scroll lock }
  114.      silent_mode [public] : boolean;
  115.                    {status message switch}
  116.      snapptr : integer;
  117.      snapscreen : array[1..20] of ^screen_buffer;
  118.      snapx, snapy : array[1..20] of integer;
  119.      speed : real;           {baud rate}
  120.      stop_bits : word;       { 1 or 2 }
  121.      telfile [public] : text;
  122.      telno : lstring(40);
  123.      vi_cursor [external] : boolean;
  124.      word_length : word;
  125.      xoff_sent [public]: boolean;
  126.      xxdate [external] : string(6);
  127.      x_control : boolean;
  128.      x_last,y_last : integer;
  129. value
  130.      adm_sim_flag := false;
  131.      bbs_numbers := false;
  132.      bios_data_ptr.r := 0;
  133.      bios_data_ptr.s := #40;
  134.      char_graphics := false;
  135.      cold_start := false;
  136.      direct_connect := false;
  137.      display_buffer_addr := 0;
  138.      display_columns := false;
  139.      display_control := false;
  140.      emacs_flag := false;
  141.      first_script.len := 0;
  142.      fts_sense := true;
  143.      function_keys[1] := 'who'*chr(13);
  144.      function_keys[2] := 'ls'*chr(13);
  145.      graftrax := true;       {assume an EPSON w/ GRAFTRAX option}
  146.      half_duplex := false;
  147.      hayes_modem := false;
  148.      hp_sim_flag := false;
  149.      ignore_char := -1;
  150.      ignore_dels := false;
  151.      ignore_rubout := false;
  152.      interrupt_set := true;
  153.      irq_num := 4;           {assume IRQ4}
  154.      last_bbs := -1;
  155.      line_edit := false;
  156.      log_flag := false;
  157.      lpt_only_flag := false;
  158.      parity := 0;           {no checking}
  159.      port_num := 0;    {assume COM1 }
  160.      prime_mode := false;
  161.      rogue_mode := false;
  162.      script_file := 'scripts';
  163.      script_verbose := false;
  164.      scroll_top := 0;
  165.      silent_mode := false;
  166.      snapptr := 1;
  167.      speed := 1200.0;       {default speed}
  168.      stop_bits := 1;
  169.      telno := 'none';
  170.      word_length := 8;
  171.      xoff_sent := false;
  172.      x_control := true;
  173.      x_last := -1;
  174.      y_last := -1;           {$include:'graph.inc'}
  175.                    {$include:'comm.inc'}
  176.  
  177.      function menutree(const s: string) : integer; external;
  178.  
  179.      procedure login; external;
  180.  
  181.      procedure keyp(i : char);external;
  182.  
  183.      procedure alogin; external;
  184.  
  185.      procedure chattr(newattr : byte;
  186.        y, sx, ex : integer); external;
  187.  
  188.      procedure ck(a : integer;
  189.        const b : string); external;
  190.  
  191.      procedure save_line(line : CRT_SIZE;
  192.        inc : INC_LIMIT); external;
  193.  
  194.      procedure display_line(line : CRT_SIZE;
  195.        inc : INC_LIMIT); external;
  196.  
  197.      procedure putchar(inchar : char); external;
  198.  
  199.      function getc(exit_flag : LOOP_FLAG) : integer; external;
  200.  
  201.      procedure parse(var c : integer); external;
  202.  
  203.      procedure endxqq; external;
  204.  
  205.      procedure parse_file(var filename : lstring); external;
  206.  
  207.      procedure down_load; external;
  208.  
  209.      procedure up_load; external;
  210.  
  211.      procedure xmodem_down; external;
  212.  
  213.      procedure xmodem_up; external;
  214.  
  215.      procedure dump_file; external;
  216.  
  217.      procedure adm_sim(ch : integer); external;
  218.  
  219.      procedure do_help(i : integer); external;
  220.  
  221.      procedure do_ventels; external;
  222.  
  223.      procedure write_file; external;
  224.  
  225.      procedure com_begin(port_num : integer;
  226.        speed : integer;
  227.        lcr : word;
  228.        xon : boolean); external;
  229.  
  230.      function modem_status : byte; external;
  231.  
  232.      procedure com_end; external;
  233.  
  234.      procedure set_interrupt_high(number : integer); external;
  235.  
  236.      procedure delete_char [public];
  237.  
  238.      var
  239.          i,x,y,ca : integer;
  240.  
  241.      begin               {delete char}
  242.          xrcurp(x,y);
  243.          for i := x to (RIGHT_MAR-1) do begin
  244.          xxmove(i+1,y);
  245.          ca:=xrca;
  246.          xxmove(i,y);
  247.          xwca(ca,1)   end;
  248.          xxmove(RIGHT_MAR,y);
  249.          xwca(NULLB,1);
  250.          xxmove(x,y);
  251.          end;
  252. { Two routine that can take a snapshot of screen w/cursor and
  253.   then later restore the snapshot }
  254.  
  255.      procedure savescreen [public];
  256.  
  257.      var
  258.          x : ads of char;
  259.  
  260.      begin
  261.          x.s := display_buffer_addr;
  262.          x.r := 0;
  263.          new(snapscreen[snapptr]);
  264.          if retrace_flag then moves_wait(x,ads snapscreen[snapptr]^,4000)
  265.          else movesl(x, ads snapscreen[snapptr]^, 4000);
  266.          xrcurp(snapx[snapptr], snapy[snapptr]);
  267.          snapptr := snapptr + 1;
  268.          end;
  269.  
  270.      procedure restorescreen [public];
  271.  
  272.      var
  273.          x : ads of char;
  274.  
  275.      begin
  276.          x.s := display_buffer_addr;
  277.          x.r := 0;
  278.          if (snapptr = 1) then return;
  279.          snapptr := snapptr - 1;
  280.          if retrace_flag then moves_wait(ads snapscreen[snapptr]^, x, 4000)
  281.          else movesl(ads snapscreen[snapptr]^, x, 4000);
  282.          xxmove(snapx[snapptr], snapy[snapptr]);
  283.          dispose(snapscreen[snapptr]);
  284.          end;
  285.  
  286.  
  287. {Binary to ASCII conversion for diplaying coordinates
  288.  on the CRT}
  289.  
  290.      procedure btoa(i:integer;
  291.        var s : string);
  292.  
  293.      begin
  294.          s[1] := chr(i div 10 + ord('0'));
  295.          if s[1] = '0' then s[1] := ' ';
  296.          s[2] := chr(i mod 10 + ord('0'));
  297.          end;
  298.  
  299.      procedure dial(var number : lstring);
  300.  
  301.      external;           {dial number on a ventel autodialer}
  302.  
  303.      function is_answered : boolean;
  304.  
  305.      external;
  306.  
  307.      procedure display_keys [public];
  308.                    {display the function key values}
  309.  
  310.      var
  311.          i,j : integer;
  312.          x,y : integer;
  313.          tchar : char;
  314.          slen : integer;
  315.  
  316.      begin
  317.          xrcurp(x,y);
  318.          xxmove(0,24);
  319.          for i := 1 to 10 do   {replace CR with ESC for displaying string}
  320.          if (function_keys[i,ord(function_keys[i,0])] = chr(13)) then function_keys[i,ord(function_keys[i,0])]
  321.                := chr(174)   ;
  322.          for i := 1 to 10 do begin
  323.          tchar := chr((i mod 10)+ord('0'));
  324.          xttywrt(tchar,#70);
  325.          if i <> 10 then slen := 7
  326.          else slen := 6;
  327.          write(function_keys[i]:slen);
  328.          end;
  329.          for i := 1 to 10 do   {UNDO the above substitution}
  330.          if (function_keys[i,ord(function_keys[i,0])] = chr(174)) then function_keys[i,ord(function_keys[i,0])]
  331.                := chr(13)   ;
  332.          xxmove(x,y);
  333.          end;
  334.  
  335.      begin
  336.      xxcls;
  337.      xxmove(0,0);
  338.      xttywrt('COPYRIGHT @ 1982 -- Jim & Eric Holtman'*chr(10)*chr(13),240);
  339.      xttywrt('----------- S I M T E R M ------------'*chr(10)*chr(13),240);
  340.      writeln(output,'Terminal Simulator Ready.       Version: ',xxdate, '            Load Address: ',cesxqq:4:16,
  341.            'H');
  342.      save_line(0,0);       {force a save to setup buffer pointers}
  343.      bios_data_ptr^[#17] := 0; {clear keyboard flag to ensure no SHIFTs are LOCKed}
  344.  
  345.      for i := 1 to argc do begin
  346.          argv(i,param);
  347.          if (param.len < 2) or (param[1] <> '-') then cycle;
  348.          case param[2] of
  349.  
  350.          'a':              {simulate an ADM3A}
  351.                adm_sim_flag := true;
  352.  
  353.          'b':              {force the monochrome display buffer}
  354.                display_buffer_addr := #B000;
  355.  
  356.          'B':              {reset the receiver buffer on a BREAK}
  357.                recv_reset := true;
  358.  
  359.          'c':              {set the comm port -  1..4}
  360.                begin
  361.              delete(param,1,2);
  362.              eval(decode(param,port_num));
  363.              if port_num = 2 then irq_num := 3; {standard default}
  364.              if (port_num < 1) or (port_num > 4) then begin
  365.              writeln(output,'illegal COMM#. COM1 assumed.');
  366.              port_num := 1;
  367.              end;
  368.              port_num := port_num-1;
  369.                    {adjust for indexing}
  370.              end;
  371.  
  372.          'd':              {direct connect -- don't wait for carrier detect}
  373.                direct_connect := true;
  374.  
  375.          'D':              {ignore the DELs -- noise on the line}
  376.                    {I have lots of noise on my line and it appears as a DEL followed by 'junk'. This
  377.                       flag filters out the offending characters}
  378.                ignore_dels := true;
  379.  
  380.          'e':              {EPSON w/o GRAFTRAX option - must simulate underlines, etc}
  381.                graftrax := false;
  382.  
  383.          'E':           {set EMACS cursors keys for `curses'}
  384.                emacs_flag := true;
  385.                
  386.          'g':              {set to graphics display buffer}
  387.                display_buffer_addr := #B800;
  388.  
  389.          'h':              {set for half-duplex mode; echo input}
  390.                half_duplex := true;
  391.  
  392.          'H': hp_sim_flag := true;
  393.  
  394.          'i':              {setup user specified IRQ for Async controller}
  395.                begin
  396.              delete(param,1,2);
  397.              eval(decode(param,irq_num));
  398.              if (irq_num < 2) or (irq_num > 5) then begin
  399.              writeln(output,'Illegal IRQ. IRQ4 assumed.');
  400.              irq_num := 4;
  401.              end;
  402.              end;
  403.         
  404.          'I':         {set comm line as highest interrupt}
  405.             if param.len = 3 then interrupt_set := false
  406.              else interrupt_set := true;
  407.              
  408.          'k':              {read in user KEY file}
  409.                begin
  410.              delete(param,1,2);
  411.              assign(key_file,param);
  412.              key_file.trap := true;
  413.              reset(key_file);
  414.              if key_file.errs = 0 then begin
  415.              while not eof(key_file) do begin
  416.                  readln(key_file,param);
  417.                  x := ord(param[1]) - ord('0');
  418.                  if x = 0 then x := 10;
  419.                  delete(param,1,2);
  420.                  if param[ord(param[0])] = chr(174) then param[ord( param[0] )] := chr(13);
  421.                  function_keys[x] := param;
  422.                  end;
  423.              close(key_file);
  424.              display_keys;
  425.              end
  426.              else writeln(output,'Key file not found - ',param);
  427.              end;
  428.  
  429.          'M': prime_mode := true;
  430.  
  431.          'm': hayes_modem := true;
  432.  
  433.          'n':              {dial the sequnece that follow the 'n' on a VenTel }
  434.                begin
  435.              delete(param,1,2);
  436.              telno := param;
  437.              end;
  438.  
  439.          'P':              {options to parse the scriptfile}
  440.              case param[3] of
  441.              'F': begin
  442.                  delete(param,1,3);
  443.                  script_file := param;
  444.                  end;
  445.              'D': begin
  446.                  delete(param,1,3);
  447.                  first_script := param;
  448.                  end;
  449.              'S': script_verbose := true;
  450.              end   ;
  451.  
  452.  
  453.          'p':              {parity}
  454.              case param[3] of
  455.  
  456.              'e':      {EVEN}
  457.                    parity := #18;
  458.  
  459.              'm':      {MARK}
  460.                    parity := #28;
  461.  
  462.              'n':      {no checking}
  463.                    parity := 0;
  464.  
  465.              'o':      {ODD}
  466.                    parity := #8;
  467.  
  468.              's':      {SPACE}
  469.                    parity := #38;
  470.  
  471.              otherwise
  472.                  writeln('illegal parity setting ',param);
  473.  
  474.              end   ;
  475.  
  476.          'o':              {turn off the status messages on errors}
  477.                silent_mode := true;
  478.  
  479.          'r':              {set to wait for retrace on color graphics}
  480.                retrace_flag := true;
  481.  
  482.          's':              {set the speed}
  483.                begin
  484.              delete(param,1,2);
  485.              eval(decode(param,speed));
  486.              end;
  487.  
  488.          'S':              {set the number of stop bits}
  489.                begin
  490.              delete(param,1,2);
  491.              eval(decode(param,stop_bits));
  492.              end;
  493.  
  494.          'v':              {setup the BBS dialing file}
  495.                begin
  496.              delete(param,1,2);
  497.              bbs_filename := param;
  498.              end;
  499.  
  500.          'w':              {set word length}
  501.                begin
  502.              delete(param,1,2);
  503.              eval(decode(param,word_length));
  504.              end;
  505.  
  506.          'x':              {XON/XOFF control}
  507.              if param[3] = 'n' then x_control := false   ;
  508.  
  509.          otherwise
  510.              writeln('illegal parameter :',param);
  511.  
  512.          end;
  513.          end;
  514.      if display_buffer_addr = 0 then      
  515.          if (bios_data_ptr^[#10] and #30) = #30 then display_buffer_addr := #B000
  516.                    {B/W monitor}
  517.          else display_buffer_addr := #B800;
  518.                    {Color/graphics board}
  519.                    {Now setup the LCR}
  520.      if parity <> 0 then word_length := word_length-1;
  521.                    {account for parity bit}
  522.      word_length := ((word_length-5) and 3) or parity;
  523.      if stop_bits = 2 then word_length := word_length or 4;
  524.                    {2 stop bits}
  525.      if interrupt_set then set_interrupt_high(irq_num);               
  526.      com_begin(irq_num*256+port_num,trunc(1843200.0/(speed*16.0)), word_length,x_control);
  527.      if not direct_connect then 
  528.          repeat
  529.          if ((modem_status and #80) = 0) and (fts_sense) then begin
  530.              fts_sense := false;
  531.              writeln(chr(7)*'Establish communications link'*chr(7))   end;
  532.                    {Check if user wants to terminate the program}
  533.          case xxinkey(inch) of
  534.                    {read data from keyboard}
  535.              0: ;       {no data, try again}
  536.  
  537.              1,2: 
  538.              case ord(inch) of
  539.                    {normal ASCII data}
  540.                  255,Alt_F1,Alt_F2: begin
  541.                    {Terminate}
  542.                  writeln(chr(7)*'Terminating the Simulator');
  543.                  write_file;
  544.                    {update bbs file}
  545.                  com_end;
  546.                  endxqq   end;
  547.  
  548.                  otherwise ;
  549.                    {ignore}
  550.                  end   ;
  551.  
  552.              end;
  553.  
  554.          until (modem_status and #80) = #80   ;
  555.      writeln('Communications established');
  556.      if (telno <> 'none') then begin
  557.          dial(telno);
  558.          end;
  559.      if (first_script.len > 0) then begin
  560.          login;
  561.          first_script.len := 0;
  562.          end;
  563.      while TRUE do begin
  564.          ch := getc(EXIT);       {get data from comm line}
  565.          if (ch > -1) then begin
  566.          if log_flag then begin
  567.              log_file^ := chr(ch);
  568.              put(log_file);
  569.              end;
  570.          if display_control then putchar(chr(ord(ch)))
  571.          else if adm_sim_flag then adm_sim(ch)
  572.          else parse(ch);
  573.          end
  574.          else if display_columns then begin
  575.          xrcurp(x,y);
  576.          if (x <> x_last) or (y <> y_last) then begin
  577.              x_last := x;
  578.              y_last := y;
  579.              btoa(x,s2);
  580.              xxmove(41,24);
  581.              xttywrt(s2,7);
  582.              btoa(y,s2);
  583.              xxmove(38,24);
  584.              xttywrt(s2,7);
  585.              xxmove(x,y);
  586.              end;
  587.          end;
  588.  
  589.          keycnt := xxinkey(inch);
  590.          if ((keycnt = 2) and (ord(inch) = 35)) then begin
  591.          menufil := '\simterm\menus';
  592.          parse_file(menufil);
  593.          x := menutree(menufil);
  594.          if (x > 1000) then begin
  595.              do_help(x);
  596.              x := 0;
  597.              keycnt := 0;
  598.              end
  599.          else begin
  600.              inch := chr(x);
  601.              if (inch <> chr(0)) then keycnt := 2
  602.              else keycnt := 0;
  603.              end;
  604.          end
  605.          else if ((keycnt=1) and (line_edit) and (inch = chr(13))) then begin
  606.          line_edit := false;
  607.          insert_mode := false;
  608.          vi_cursor := false;
  609.          inch := chr(INSERT_KEY);
  610.          keycnt := 2;
  611.          end;
  612.          case keycnt of       {read data from keyboard}
  613.          0: ;           {no data, try again}
  614.  
  615.          1:       
  616.              case ord(inch) of
  617.                    {normal ASCII data}
  618.              255: begin{Terminate}
  619.                  writeln(chr(7)*'Terminating the Simulator');
  620.                  write_file;
  621.                    {update bbs file}
  622.                  com_end;
  623.                  endxqq   end;
  624.  
  625.              otherwise
  626.                  if (half_duplex or line_edit) then putchar(chr( inch));
  627.                  if not line_edit then send(inch);
  628.                    {output character}
  629.              end ;
  630.  
  631.          2: keyp(inch);
  632.          end;
  633.          end;
  634.      end.
  635.  
  636.  
  637.